package com.zy.service.hrm.impl;

import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.zy.dao.hrm.TeamDao;
import com.zy.entity.enums.StatusEnum;
import com.zy.entity.hrm.Team;
import com.zy.entity.sys.User;
import com.zy.pojo.constants.Constant;
import com.zy.pojo.exceptions.ExceptionEnum;
import com.zy.pojo.exceptions.ServiceException;
import com.zy.pojo.vos.common.PageVo;
import com.zy.service.base.impl.BaseServiceImpl;
import com.zy.service.hrm.TeamService;
import com.zy.utils.DateUtil;

@Service("teamService")
public class TeamServiceImpl extends BaseServiceImpl<Team> implements TeamService {

	@Autowired
	private TeamDao teamDao;

	@Override
	public PageVo pageTeam(Team team, int start, int limit) {
		return new PageVo(start, limit, this.teamDao.countTeam(team), this.teamDao.listTeam(team, start, limit));
	}

	@Override
	public void saveTeam(Team team) {
		String teamName = team.getTeamName().trim();
		Team teamNameParam = new Team();
		teamNameParam.setTeamName(teamName);
		if (this.teamDao.getCount(teamNameParam) > 0) {
			throw new ServiceException(ExceptionEnum.TEAM_NAME_EXISTED);
		}
		long time = DateUtil.getTime();
		team.setCreateTime(time);
		team.setModifyTime(time);
		team.setStatus(StatusEnum.NORMAL.getValue());
		this.teamDao.save(team);
	}

	@Override
	public void updateTeam(Team team) {
		String teamName = team.getTeamName().trim();
		Team teamNameParam = new Team();
		teamNameParam.setTeamName(teamName);
		Team teamNaemTeam = this.teamDao.get(teamNameParam);
		if (teamNaemTeam != null && teamNaemTeam.getId().longValue() != team.getId()) {
			throw new ServiceException(ExceptionEnum.TEAM_NAME_EXISTED);
		}
		team.setModifyTime(DateUtil.getTime());
		this.teamDao.updateByPrimaryKeySelective(team);
	}

	@Override
	public Team move(long id, long parentId) {
		Team team = this.teamDao.getByPrimaryKey(id);
		team.setParentId(parentId);
		team.setModifyTime(DateUtil.getTime());
		this.teamDao.updateByPrimaryKey(team);
		return team;
	}

	@Override
	public boolean removeTeam(long id) {
		try {
			this.teamDao.removeByPrimaryKey(id);
			return true;
		} catch (Exception e) {
			log.info(e.getMessage(), e);
			Team team = new Team();
			team.setId(id);
			team.setModifyTime(DateUtil.getTime());
			team.setStatus(StatusEnum.DELETE.getValue());
			this.teamDao.updateByPrimaryKeySelective(team);
			return false;
		}
	}

	@Override
	public void recover(long id) {
		Team team = new Team();
		team.setId(id);
		team.setModifyTime(DateUtil.getTime());
		team.setStatus(StatusEnum.NORMAL.getValue());
		this.teamDao.updateByPrimaryKeySelective(team);
	}

	@Override
	public Team listTeam() {
		Subject subject = SecurityUtils.getSubject();
		Team root = new Team();
		if (subject.hasRole(Constant.ADMIN)) {
			root.setId(Constant.ROOT);
			this.appendNode(root, this.teamDao.listAll());
		} else {
			long userId = ((User) subject.getSession().getAttribute(Constant.CURRENT_USER)).getId();
			Team team = this.teamDao.getTeamByUserId(userId);
			root.getChildren().add(team);
			this.appendNode(team, this.teamDao.listAll());
		}
		return root;
	}

	@Override
	public Team listChecked() {
		Subject subject = SecurityUtils.getSubject();
		Team root = new Team();
		if (subject.hasRole(Constant.ADMIN)) {
			root.setId(Constant.ROOT);
			this.appendCheckedNode(root, this.teamDao.listAll());
		} else {
			long userId = ((User) subject.getSession().getAttribute(Constant.CURRENT_USER)).getId();
			Team team = this.teamDao.getTeamByUserId(userId);
			team.setChecked(false);
			team.setExpanded(true);
			root.getChildren().add(team);
			this.appendCheckedNode(team, this.teamDao.listAll());
		}
		return root;
	}

	private void appendNode(Team root, List<Team> teams) {
		for (Team node : teams) {
			if (node.getParentId().longValue() == root.getId()) {
				root.getChildren().add(node);
				appendNode(node, teams);
			}
		}
	}

	private void appendCheckedNode(Team root, List<Team> teams) {
		for (Team node : teams) {
			node.setChecked(false);
			node.setExpanded(true);
			if (node.getParentId().longValue() == root.getId()) {
				root.getChildren().add(node);
				appendNode(node, teams);
			}
		}
	}

}
